//
//  HNRequest.swift
//  Supermarket
//
//  Created by liuxm on 2017/8/8.
//  Copyright © 2017年 kushao. All rights reserved.
//

import UIKit
import Alamofire


protocol KSRequestDelegate: NSObjectProtocol {
    
    /// 请求成功
    ///
    /// - Parameters:
    ///   - result: 返还JSON
    ///   - apiType: 请求的接口类型
    func requestSuccess(result: String, apiType:KSApiType)
    
    /// 请求失败
    ///
    /// - Parameters:
    ///   - message: 错误消息
    ///   - code: 错误Code
    ///   - apiType: 请求的接口类型
    func requestFaile(code: Int, message: String, apiType:KSApiType)
}

/// 网络请求
class KSRequest: NSObject {
    
    weak var delegate: KSRequestDelegate?
    
    /// 接口请求
    ///
    /// - Parameters:
    ///   - parameters: 参数
    ///   - apiType: Api类型
    func excuteRequestWithParameters(parameters:[String: Any], apiType:KSApiType) {
        let url = KSRequestConfig.kServiceUrl + self.getUrl(apiType: apiType)
        let method = self.getMethod(apiType: apiType)
        
        var headers:HTTPHeaders = [
            "Accept": "application/json"
        ]
        
        if !KSUserDefaultsTools.getUserToken().isEmpty {
            headers = [
                "Accept": "application/json",
                "Authorization": "Bearer " + KSUserDefaultsTools.getUserToken()
            ]
        }
        
        Alamofire.request(url, method: method, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON { (response) in
            switch response.result {
            case .success(let data):
                let json = data as! [String: Any]
                let data = try? JSONSerialization.data(withJSONObject: json, options: JSONSerialization.WritingOptions.prettyPrinted)
                let jsonStr = String(data: data!, encoding: .utf8)
                self.handleRequestSuccess(response: jsonStr!, apiType: apiType)
            case .failure(let error):
                let err = error as NSError
                self.handleFailureResponseWithErrCode(code: err.code, apiType: apiType)
            }
        }
    }
    
    /// 图片上传
    ///
    /// - Parameters:
    ///   - parameters: 参数
    ///   - apiType: Api类型
    func excutePhotoUploadWithParameters(type:String, datas:[String: Any], apiType:KSApiType) {
        let url = KSRequestConfig.kServiceUrl + self.getUrl(apiType: apiType)
        
        Alamofire.upload(multipartFormData: { (multipartFormData) in
            //字符串
            let typeData = type.data(using: String.Encoding.utf8)
            multipartFormData.append(typeData!, withName: "type")
            
            for data in datas {
                let imageData:Data = data.value as! Data
                let imageName = String(describing: NSDate()) + ".png"
                multipartFormData.append(imageData, withName: data.key, fileName: imageName, mimeType: "image/png")
            }
        }, to: url) { (encodingResult) in
            switch encodingResult {
            case .success(let upload, _, _):
                upload.responseJSON { response in
                    let result = response.result
                    if result.isSuccess {
                        let data = try? JSONSerialization.data(withJSONObject: result.value!, options: JSONSerialization.WritingOptions.prettyPrinted)
                        let jsonStr = String(data: data!, encoding: .utf8)
                        self.handleRequestSuccess(response: jsonStr!, apiType: apiType)
                    }
                }
            case .failure(let error):
                let err = error as NSError
                self.handleFailureResponseWithErrCode(code: err.code, apiType: apiType)
            }
        }
    }
}

extension KSRequest {
    fileprivate func handleRequestSuccess(response: String, apiType:KSApiType) {
        if !response.isEmpty {
            let baseModel = KSBaseModel.deserialize(from: response)
            if baseModel != nil {
                // 请求成功
                if baseModel?.code == 200 {
                    if self.delegate != nil {
                        self.delegate?.requestSuccess(result: response, apiType: apiType)
                    }
                } else {
                    if self.delegate != nil {
                        self.delegate?.requestFaile(code: (baseModel?.code)!, message: (baseModel?.message)!, apiType: apiType)
                    }
                }
            }
        }
    }
    
    fileprivate func handleFailureResponseWithErrCode(code: Int, apiType:KSApiType) {
        var message: String = "对不起，服务器未响应！"
        switch code {
        case -1009:
            message = "没有网络啦！"
        case -1001:
            message = "对不起，访问超时啦！"
        default:
            break
        }
        
        if self.delegate != nil {
            self.delegate?.requestFaile(code: code, message: message, apiType: apiType)
        }
    }
}

extension KSRequest {
    
    /// 获取Api地址
    ///
    /// - Parameter apiType: 请求Api
    /// - Returns: url
    fileprivate func getUrl(apiType: KSApiType) -> String {
        var url = ""
        if let apiInfo = KSRequestConfig.kApiDictionary[apiType.rawValue] {
            url = apiInfo.url
        }
        
        return url
    }
    
    /// 获取请求类型
    ///
    /// - Parameter apiType: 请求Api
    /// - Returns: 类型Get/Post
    fileprivate func getMethod(apiType: KSApiType) -> HTTPMethod {
        var method = HTTPMethod(rawValue: HTTPMethod.post.rawValue)!
        if let apiInfo = KSRequestConfig.kApiDictionary[apiType.rawValue] {
            if apiInfo.httpType == KSHttpType.KSHttpGet.rawValue {
                method = HTTPMethod(rawValue: HTTPMethod.get.rawValue)!
            }
        }
        
        return method
    }
    
    /// 参数不加密
    ///
    /// - params : 参数
    /// - Returns: 加密后的参数
    fileprivate func addCommonParams(params: [String: Any]) -> [String: Any] {
        let version = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String
        let dict:NSMutableDictionary = NSMutableDictionary(dictionary: params)
        if KSUserDefaultsTools.getUserToken().isEmpty {
            let appInfo: [String: Any] = ["os": "ios", "version": version]
            dict.addEntries(from: appInfo)
        } else {
            let appInfo: [String: Any] = ["os": "ios", "version": version, "userId": KSUserDefaultsTools.getUserId()]
            dict.addEntries(from: appInfo)
        }
        
        return dict as! [String : Any]
    }
}
